package org.jeecg.modules.param.area.service.impl;

import cn.hutool.core.lang.tree.TreeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.constant.BikeConstant;
import org.jeecg.modules.param.area.dto.BikeSysAreaRes;
import org.jeecg.modules.param.area.entity.BikeSysArea;
import org.jeecg.modules.param.area.entity.BikeSysUserArea;
import org.jeecg.modules.param.area.mapper.BikeSysAreaMapper;
import org.jeecg.modules.param.area.mapper.BikeSysUserAreaMapper;
import org.jeecg.modules.param.area.service.IBikeSysAreaService;
import org.jeecg.modules.param.station.entity.BikeStation;
import org.jeecg.modules.param.station.mapper.BikeStationMapper;
import org.jeecg.modules.param.area.dto.BikeSysAreaTree;
import org.jeecg.modules.param.area.dto.TreeRes;
import org.jeecg.modules.system.permissions.entity.BikeSysUserApp;
import org.jeecg.modules.system.permissions.mapper.BikeSysUserAppMapper;
import org.jeecg.modules.utils.MD5Utils;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description: bike_sys_area
 * @Author: 月月鸟
 * @Date: 2021-05-18
 * @Version: V1.0
 */
@Service
@Slf4j
public class BikeSysAreaServiceImpl extends ServiceImpl<BikeSysAreaMapper, BikeSysArea> implements IBikeSysAreaService {

    @Resource
    private BikeSysUserAreaMapper bikeSysUserAreaMapper;
    @Resource
    private BikeSysAreaMapper bikeSysAreaMapper;
    @Resource
    private BikeStationMapper bikeStationMapper;

    @Override
    public List<BikeSysArea> getFatherNameList(BikeSysArea bikeSysArea, int type) {
        QueryWrapper<BikeSysArea> queryWrapper = new QueryWrapper<>();
        //查询区域 id，编号，名称，父级id
        //queryWrapper.select("id","area_code","name","parent_id","has_child","create_time","memo");
        if (bikeSysArea.getId() != null) {
            String id = bikeSysArea.getId();
            String[] split = id.split(",");
            List<String> strings = Arrays.asList(split);
            queryWrapper.in("id", strings);
        }
        if (type == 1) {
            //状态为1
            queryWrapper.eq("status", 1);

        }
        return bikeSysAreaMapper.selectList(queryWrapper);
    }

    @Override
    public List<BikeSysArea> getSiteTree(BikeSysUserArea bikeSysUserArea) {
        BikeSysArea bikeSysArea = new BikeSysArea();
        String[] split = null;
        if (bikeSysUserArea.getAreaId() != null) {
            bikeSysArea.setId(bikeSysUserArea.getAreaId());
        }
        if (bikeSysUserArea.getAreaId() != null) {
            split = bikeSysUserArea.getAreaId().split(",");
        }
        List<BikeSysArea> fatherNameList = getFatherNameList(bikeSysArea, 1);
        for (BikeSysArea tb : fatherNameList) {
            if (tb.getHasChild().equals("0")) {
                QueryWrapper qw = new QueryWrapper<>();
                qw.select("id", "name", "code");
                if (split != null) {
                    qw.in("id", split);
                }
                qw.eq("area_id", tb.getId());
                List list = bikeStationMapper.selectList(qw);
                if (list != null) {
                    tb.setChildren(list);
                }
            }
        }
        List<BikeSysArea> bikeSysAreas = buidTree(fatherNameList);
        return bikeSysAreas;
    }

    @Override
    public List<BikeSysArea> getOrganizationTree(BikeSysArea bikeSysArea, int type) {
        List<BikeSysArea> fatherNameList = getFatherNameList(bikeSysArea, type);

        return buidTree(fatherNameList);
    }

    /**
     * 条件查询 以及下级树
     */
    @Override
    public List<BikeSysArea> getReqTree(List<BikeSysArea> list) {
        QueryWrapper<BikeSysArea> wrapper = new QueryWrapper<>();
        List<BikeSysArea> bikeSysAreas = bikeSysAreaMapper.selectList(wrapper);
        for (BikeSysArea bsa : list) {
            if (bsa.getHasChild().equals(BikeConstant.y_n_yes)) {
                this.findChild(bsa, bikeSysAreas);
            }
        }
        return list;
    }

    @Override
    public void addAreaUser(LoginUser sysUser, String toString) {
        QueryWrapper<BikeSysUserArea> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", sysUser.getUsername());
        BikeSysUserArea bikeSysUserArea = bikeSysUserAreaMapper.selectOne(wrapper);
        if (bikeSysUserArea != null) {
            bikeSysUserArea.setAreaId(bikeSysUserArea.getAreaId() + "," + toString);
            bikeSysUserAreaMapper.updateById(bikeSysUserArea);
        } else {
            BikeSysUserArea newUserArea = new BikeSysUserArea();
            newUserArea.setAreaId(toString);
            newUserArea.setUserId(sysUser.getUsername());
            bikeSysUserAreaMapper.insert(newUserArea);
        }

    }

    //导入
    @Override
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            String err = "";
            StringBuilder err2 = new StringBuilder();

            try {
                long start = System.currentTimeMillis();
                List<BikeSysArea> list = ExcelImportUtil.importExcel(file.getInputStream(), BikeSysArea.class, params);
                //执行2遍，补充父级信息
                for (int i = 0 ; i <= 1 ; i++){
                    for (BikeSysArea tb : list) {
                        BikeSysArea cloneTb = tb.clone();
                        if (StringUtils.isEmpty(cloneTb.getParentId())) {
                            //如果为空，判断为最高级
                            cloneTb.setParentId("0");
                        }
                        if (StringUtils.isNotEmpty(cloneTb.getAreaCode()) && StringUtils.isNotEmpty(cloneTb.getName())) {
                            //仅导入 编号 名称不为空
                            //区域编号去空
                            if (StringUtils.isNotEmpty(cloneTb.getAreaCode())) {
                                cloneTb.setAreaCode(cloneTb.getAreaCode().replace(" ", ""));
                            }
                            //名称去空
                            if (StringUtils.isNotEmpty(cloneTb.getParentId())) {
                                cloneTb.setParentId(cloneTb.getParentId().replace(" ", ""));
                            }

                            if (StringUtils.isEmpty(cloneTb.getStatus())){
                                //状态空 则为禁用
                                cloneTb.setStatus("0");
                            }
                            if (!cloneTb.getParentId().equals("0")) {
                                //判断非无父级
                                //通过导出数据，获取自身数据
                                List<BikeSysArea> areaCode = bikeSysAreaMapper.selectList(new QueryWrapper<BikeSysArea>()
                                        .eq("area_code", cloneTb.getAreaCode()));
                                if (areaCode.size()>1){
                                    if (err2.toString().equals("")){
                                        err2 = new StringBuilder(";以下区域编号重复，请修改后提交：" + cloneTb.getName() + ";");
                                    }else {
                                        err2.append(cloneTb.getName()).append(";");
                                    }
                                    continue;
                                }
                                //通过导出数据，获取父级数据
                                BikeSysArea pArea = new BikeSysArea();
                                pArea = bikeSysAreaMapper.selectById(cloneTb.getParentId());
                                if (pArea==null){
                                    pArea = bikeSysAreaMapper.selectOne(new QueryWrapper<BikeSysArea>()
                                            .eq("area_code", cloneTb.getParentId().replace(" ","")));
                                }
                                if (areaCode.isEmpty()) {
                                    //自身不存在
                                    if (pArea == null) {
                                        //父级不存在
                                        cloneTb.setParentId("0");
                                    } else {
                                        //父级存在
                                        cloneTb.setParentId(pArea.getId());
                                        if (pArea.getHasChild().equals(BikeConstant.y_n_no)){
                                            pArea.setHasChild(BikeConstant.y_n_yes);
                                            bikeSysAreaMapper.updateById(pArea);
                                        }
                                    }
                                    bikeSysAreaMapper.insert(cloneTb);
                                } else {
                                    BikeSysArea bikeSysArea = areaCode.get(0);
                                    //自身存在
                                    cloneTb.setId(bikeSysArea.getId());
                                    if (pArea == null) {
                                        //父级不存在
                                        cloneTb.setParentId("0");
                                        if (i==1){
                                            if (err.equals("")){
                                                err=";以下区域父级区域编号不存在，默认最高级,请及时修改："+bikeSysArea.getName()+";";
                                            }else {
                                                err=err+pArea.getName()+":父级区域不存在;";
                                            }
                                        }
                                    } else {
                                        //父级存在
                                        cloneTb.setParentId(pArea.getId());
                                        if (pArea.getHasChild().equals(BikeConstant.y_n_no)){
                                            pArea.setHasChild(BikeConstant.y_n_yes);
                                            bikeSysAreaMapper.updateById(pArea);
                                        }
                                    }
                                    bikeSysAreaMapper.updateById(cloneTb);
                                }

                            } else {
                                //判断为最高级
                                //通过导出数据，获取自身数据
                                BikeSysArea bikeSysArea = bikeSysAreaMapper.selectOne(new QueryWrapper<BikeSysArea>()
                                        .eq("area_code", cloneTb.getAreaCode()));
                                if (bikeSysArea == null) {
                                    //自身不存在
                                    bikeSysAreaMapper.insert(cloneTb);
                                } else {
                                    //自身存在
                                    cloneTb.setId(bikeSysArea.getId());
                                    bikeSysAreaMapper.updateById(cloneTb);
                                }
                            }
                        }
                    }
                }
                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒;");
                return Result.ok("文件导入成功！数据行数：" + list.size()+err2+err);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {

                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }

    @Override
    public List<BikeSysArea> getExportXlsList(BikeSysArea bikeSysArea) {
        List<BikeSysArea> list = bikeSysAreaMapper.getList();
        return list;
    }

    //建立树
    public List<BikeSysArea> buidTree(List<BikeSysArea> list) {
        List<BikeSysArea> tree = new ArrayList<>();
        for (BikeSysArea node : list) {
            if (node.getParentId().equals("0")) {
                tree.add(findChild(node, list));
            }
        }
        return tree;
    }

    //找子节点
    public BikeSysArea findChild(BikeSysArea node, List<BikeSysArea> list) {
        for (BikeSysArea n : list) {
            if (n.getParentId().equals(node.getId())) {
                //如果有子节点
                if (node.getChildren() == null) {
                    node.setChildren(new ArrayList<BikeSysArea>());
                }
                node.getChildren().add(findChild(n, list));
            }
        }
        return node;
    }


    @Override
    public String addBikeSysArea(BikeSysArea bikeSysArea) {
        if (oConvertUtils.isEmpty(bikeSysArea.getParentId())) {
            bikeSysArea.setParentId(IBikeSysAreaService.ROOT_PID_VALUE);
        } else {
            //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
            BikeSysArea parent = baseMapper.selectById(bikeSysArea.getParentId());
            //判断父级是否为最下级
            if (parent.getHasChild().equals(BikeConstant.y_n_no)) {
                //查询父节点是否绑定站点
                QueryWrapper<BikeStation> wrapper = new QueryWrapper<>();
                wrapper.eq("area_id", parent.getParentId());
                List<BikeStation> stations = bikeStationMapper.selectList(wrapper);
                if (stations.size() != 0) {
                    return "该区域已绑定网点，无法添加下级";
                }
            }
            if (parent != null && !"1".equals(parent.getHasChild())) {
                parent.setHasChild("1");
                baseMapper.updateById(parent);
            }
        }
        baseMapper.insert(bikeSysArea);
        return BikeConstant.y_n_yes;
    }

    @Override
    public String addCheck(BikeSysArea bikeSysArea) {
        BikeSysArea data = bikeSysAreaMapper.selectById(bikeSysArea.getId());
        //判断是否为最下级
        if (data.getHasChild().equals(BikeConstant.y_n_no)) {
            //查询父节点是否绑定站点
            QueryWrapper<BikeStation> wrapper = new QueryWrapper<>();
            wrapper.eq("area_id", bikeSysArea.getId());
            List<BikeStation> stations = bikeStationMapper.selectList(wrapper);
            if (stations.size() != 0) {
                return "该区域已绑定网点，无法添加下级";
            }
        }

        return BikeConstant.y_n_yes;
    }

    @Override
    public void updateBikeSysArea(BikeSysArea bikeSysArea) {
        BikeSysArea entity = this.getById(bikeSysArea.getId());
        if (entity == null) {
            throw new JeecgBootException("未找到对应实体");
        }
        String old_pid = entity.getParentId();
        String new_pid = bikeSysArea.getParentId();
        if (!old_pid.equals(new_pid)) {
            updateOldParentNode(old_pid);
            if (oConvertUtils.isEmpty(new_pid)) {
                bikeSysArea.setParentId(IBikeSysAreaService.ROOT_PID_VALUE);
            }
            if (!IBikeSysAreaService.ROOT_PID_VALUE.equals(bikeSysArea.getParentId())) {
                baseMapper.updateTreeNodeStatus(bikeSysArea.getParentId(), IBikeSysAreaService.HASCHILD);
            }
        }
        baseMapper.updateById(bikeSysArea);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> deleteBikeSysArea(String id) throws JeecgBootException {
        //查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if (id.indexOf(",") > 0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if (idVal != null) {
                    BikeSysArea bikeSysArea = this.getById(idVal);
                    String pidVal = bikeSysArea.getParentId();
                    //查询此节点上一级是否还有其他子节点
                    List<BikeSysArea> dataList = baseMapper.selectList(new QueryWrapper<BikeSysArea>().eq("parent_id", pidVal).notIn("id", Arrays.asList(idArr)));
                    if ((dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal)
                            && !sb.toString().contains(pidVal)) {
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            List<String> idArray = Arrays.asList(idArr);
            for (int i = 0; i < idArray.size(); i++) {
                String s = idArray.get(i);
                QueryWrapper<BikeStation> wrapper = new QueryWrapper<>();
                wrapper.eq("area_id", s);
                List<BikeStation> bikeStations = bikeStationMapper.selectList(wrapper);
                if (bikeStations.size() != 0) {
                    return Result.error("区域已绑定网点，无法删除");
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(idArray);
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for (String pid : pidArr) {
                this.updateOldParentNode(pid);
            }
            return Result.OK("删除成功");
        } else {
            BikeSysArea bikeSysArea = this.getById(id);
            if (bikeSysArea == null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(bikeSysArea.getParentId());
            QueryWrapper<BikeStation> wrapper = new QueryWrapper<>();
            wrapper.eq("area_id", id);
            List<BikeStation> bikeStations = bikeStationMapper.selectList(wrapper);
            if (bikeStations.size() != 0) {
                return Result.error("区域已绑定网点，无法删除");
            } else {
                baseMapper.deleteById(id);
                return Result.OK("删除成功");
            }
        }
    }

    @Override
    public List<BikeSysArea> queryTreeListNoPage(QueryWrapper<BikeSysArea> queryWrapper) {
        List<BikeSysArea> dataList = baseMapper.selectList(queryWrapper);
        List<BikeSysArea> mapList = new ArrayList<>();
        for (BikeSysArea data : dataList) {
            String pidVal = data.getParentId();
            //递归查询子节点的根节点
            if (pidVal != null && !"0".equals(pidVal)) {
                BikeSysArea rootVal = this.getTreeRoot(pidVal);
                if (rootVal != null && !mapList.contains(rootVal)) {
                    mapList.add(rootVal);
                }
            } else {
                if (!mapList.contains(data)) {
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }


    /**
     * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
     *
     * @param pid
     */
    private void updateOldParentNode(String pid) {
        if (!IBikeSysAreaService.ROOT_PID_VALUE.equals(pid)) {
            Integer count = baseMapper.selectCount(new QueryWrapper<BikeSysArea>().eq("parent_id", pid));
            if (count == null || count <= 1) {
                baseMapper.updateTreeNodeStatus(pid, IBikeSysAreaService.NOCHILD);
            }
        }
    }

    /**
     * 递归查询节点的根节点
     *
     * @param pidVal
     * @return
     */
    private BikeSysArea getTreeRoot(String pidVal) {
        BikeSysArea data = baseMapper.selectById(pidVal);
        if (data != null && !"0".equals(data.getParentId())) {
            return this.getTreeRoot(data.getParentId());
        } else {
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     *
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if (pidVal != null) {
                if (!sb.toString().contains(pidVal)) {
                    if (sb.toString().length() > 0) {
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal, sb);
                }
            }
        }
        return sb.toString();
    }
    /**
     * 递归查询所有子节点
     *
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) {
        List<BikeSysArea> dataList = baseMapper.selectList(new QueryWrapper<BikeSysArea>().eq("parent_id", pidVal));
        if (dataList != null && dataList.size() > 0) {
            for (BikeSysArea tree : dataList) {
                if (!sb.toString().contains(tree.getId())) {
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(), sb);
            }
        }
        return sb;
    }

}
